package com.example.designpatterns.command.macro;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.example.designpatterns.command.Command;

/**
 * MacroCommand类 - 宏命令，可以同时执行多个命令
 */
public class MacroCommand implements Command {
    private List<Command> commands;
    private String name;
    
    /**
     * 创建一个空的宏命令
     * @param name 宏命令名称
     */
    public MacroCommand(String name) {
        this.name = name;
        this.commands = new ArrayList<>();
    }
    
    /**
     * 使用命令列表创建宏命令
     * @param name 宏命令名称
     * @param commands 要包含的命令列表
     */
    public MacroCommand(String name, Command... commands) {
        this.name = name;
        this.commands = new ArrayList<>(Arrays.asList(commands));
    }
    
    /**
     * 添加命令到宏命令
     * @param command 要添加的命令
     */
    public void addCommand(Command command) {
        commands.add(command);
    }
    
    /**
     * 移除命令
     * @param command 要移除的命令
     * @return 是否成功移除
     */
    public boolean removeCommand(Command command) {
        return commands.remove(command);
    }
    
    /**
     * 清空所有命令
     */
    public void clearCommands() {
        commands.clear();
    }
    
    @Override
    public void execute() {
        System.out.println("执行宏命令: " + name);
        for (Command command : commands) {
            System.out.println("- 执行子命令: " + command.getName());
            command.execute();
        }
    }
    
    @Override
    public boolean undo() {
        System.out.println("撤销宏命令: " + name);
        // 逆序撤销命令
        for (int i = commands.size() - 1; i >= 0; i--) {
            Command command = commands.get(i);
            System.out.println("- 撤销子命令: " + command.getName());
            if (!command.undo()) {
                System.out.println("  撤销失败: " + command.getName());
            }
        }
        return true;
    }
    
    @Override
    public String getName() {
        return name;
    }
    
    /**
     * 获取宏命令中的子命令数量
     * @return 子命令数量
     */
    public int getCommandCount() {
        return commands.size();
    }
} 